package iot

import (
	"fmt"
	"sync"
	"time"

	"charging_pile/netty/internal/svc"
	"charging_pile/util/protocol/mq"

	"github.com/go-netty/go-netty"
	go_cache "github.com/patrickmn/go-cache"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/netx"
	"github.com/zeromicro/go-zero/core/service"
)

// var _ def.Netty = (*server)(nil)

type server struct {
	listenOn     string
	bootstrap    netty.Bootstrap
	SnChannelMap sync.Map
	SvcCtx       *svc.ServiceContext
	Mutex        sync.Mutex
	LocalIP      string
	Cache        *go_cache.Cache
}

func NewIoTService(SvcCtx *svc.ServiceContext) service.Service {
	srv := &server{
		listenOn:     SvcCtx.Config.NettyAddr,
		SnChannelMap: sync.Map{},
		SvcCtx:       SvcCtx,
		LocalIP:      netx.InternalIp(),
	}

	srv.Cache = go_cache.New(5*time.Minute, 10*time.Minute)

	bs := netty.NewBootstrap(netty.WithChildInitializer(func(channel netty.Channel) {
		channel.Pipeline().
			AddLast(PacketCodec(4096)).
			AddLast(JiuxingSubpackage()).
			AddLast(NewMsgHandler(srv))
	}))
	srv.bootstrap = bs
	SvcCtx.Netty = srv

	return srv
}

func (n *server) Start() {
	fmt.Printf("listen on:%s\n", n.listenOn)
	n.bootstrap.Listen(n.listenOn).Sync()
}

func (n *server) Stop() {
	n.bootstrap.Shutdown()
}

func (n *server) HandleMqMsg(msg mq.Msg) {
	ch, ok := n.SnChannelMap.Load(msg.Sn)
	if !ok {
		logx.Errorf("not found channel:%s", msg.Sn)
		return
	}
	c, ok := ch.(netty.Channel)
	if !ok {
		logx.Error("not found channe -1.0")
		return
	}
	c.Write(msg)

}
